package store

import (
	"file_explorer/common/log"
	"fmt"
	"sort"

	"file_explorer/common/consts"
	"file_explorer/common/util"
	"file_explorer/model"
	"file_explorer/service"
	"file_explorer/service/eventbus"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/theme"
)

type FileTabContext struct {
	DefaultTabContext

	Filters []model.Filter
	Depth   int

	DirNodes    []string
	FileInfos   []*model.FileInfo
	CheckedList []*model.FileInfo

	sortFunc func(a, b *model.FileInfo) bool
}

func (ctx *FileTabContext) GetTabType() string {
	return consts.TabTypeFile
}

func (ctx *FileTabContext) GetTabLabel() string {
	return fmt.Sprintf("%s: %s", ctx.GetTabType(), ctx.GetDirName())
}

func (ctx *FileTabContext) GetTabIcon() fyne.Resource {
	return theme.FolderOpenIcon()
}

// 获取当前绝对路径
func (ctx *FileTabContext) GetPath() string {
	return util.PathJoin(ctx.DirNodes...)
}

func (ctx *FileTabContext) GetDirName() string {
	return ctx.DirNodes[len(ctx.DirNodes)-1]
}

func (ctx *FileTabContext) SetSortFunc(cmp func(a, b *model.FileInfo) bool) {
	ctx.sortFunc = cmp
	sort.Slice(ctx.FileInfos, func(i, j int) bool {
		return ctx.sortFunc(ctx.FileInfos[i], ctx.FileInfos[j])
	})
}

func (ctx *FileTabContext) ResetFilters() {
	ctx.Filters = nil
	ctx.Depth = 0
	ctx.RefreshPath()
}

// 刷新当前目录
func (ctx *FileTabContext) RefreshPath() {
	log.Info("刷新文件目录，路径：%s", ctx.GetPath())
	ctx.OpenDir(ctx.GetPath())
}

// 指定目录，查询文件列表
func (ctx *FileTabContext) OpenDir(path string) {
	oldPath := ctx.GetPath()

	// 更新目录、文件列表
	ctx.DirNodes, ctx.FileInfos = ctx.queryPath(util.PathSplit2Nodes(path))
	sort.Slice(ctx.FileInfos, func(i, j int) bool {
		return ctx.sortFunc(ctx.FileInfos[i], ctx.FileInfos[j])
	})

	// 清空选中文件
	ctx.CheckedList = make([]*model.FileInfo, 0)

	// 更新tab标题
	if ctx.tabItem != nil {
		ctx.tabItem.Text = ctx.GetTabLabel()
	}

	ctx.ProduceEvent(eventbus.EventKeyFileTabPathChange, map[string]interface{}{
		"old_path": oldPath,
		"new_path": ctx.GetPath(),
	})
}

// 查询目录下子文件
func (ctx *FileTabContext) queryPath(dirNodes []string) ([]string, []*model.FileInfo) {
	path := util.PathJoin(dirNodes...)
	filter := func(info *model.FileInfo) bool {
		for _, f := range ctx.Filters {
			if !f.Filter(info) {
				return false
			}
		}
		return true
	}

	fileInfos, err := service.QueryFilesRecursive(path, model.GetDefaultOption().
		SetDepth(ctx.Depth).
		SetShowVirtualFile(ctx.GetGlobalConf().ShowVirtualFile).
		SetFilter(filter))
	if err == nil {
		return util.PathSplit2Nodes(path), fileInfos
	}

	// 查询报错时返回上级再查，此时不做过滤，返回最终查到的目录和文件列表
	for true {
		dirNodes = dirNodes[:len(dirNodes)-1]
		path = util.PathJoin(dirNodes...)
		fileInfos, err = service.QueryFiles(path, model.GetDefaultOption().
			SetShowVirtualFile(ctx.GetGlobalConf().ShowVirtualFile))
		if err == nil {
			return util.PathSplit2Nodes(path), fileInfos
		}
	}
	return nil, nil
}

func NewFileTabContext(gCtx *GlobalContext, path string) *FileTabContext {
	if !util.PathIsDir(path) {
		return nil
	}

	ctx := &FileTabContext{
		DefaultTabContext: newDefaultTabContext(gCtx),
		DirNodes:          util.PathSplit2Nodes(path),
		sortFunc: func(a, b *model.FileInfo) bool {
			return util.CmpText(a.Name, b.Name) > 0
		},
	}

	return ctx
}
